package com.ciei.dpagm.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class SocketClient {

    private Logger logger = LoggerFactory.getLogger(SocketClient.class);

    private Socket socket;
    private InputStream inputStream;
    private OutputStream outputStream;

    public SocketClient(Socket socket) throws IOException {
        this.socket = socket;
        this.inputStream = socket.getInputStream();
        this.outputStream = socket.getOutputStream();
    }

    public SocketClient(String host, int port) throws IOException {
        this.socket = new Socket(host, port);
        socket.setOOBInline(true);
        socket.setKeepAlive(true);
        this.inputStream = socket.getInputStream();
        this.outputStream = socket.getOutputStream();
    }

    /**
     * 登出操作, 关闭各种流
     */
    public void logout() {
        try {
            socket.shutdownOutput();
            socket.shutdownInput();
        } catch (IOException e) {
            logger.error("关闭Socket输入输出失败", e);
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                logger.error("关闭Socket失败", e);
            }
        }
    }

    /**
     * 发送数据
     * @param msg    发送的消息
     * @return       是否发送成功
     */
    public boolean send(String msg) {
        if (!isSocketClosed()){
            try {
                outputStream.write(msg.getBytes());
                return true;
            } catch (IOException e) {
                logger.error("Socket发送数据失败", e);
            }
        }
        return false;
    }

    /**
     * 接收数据
     * @return      接收的消息
     */
    public String receive() {
        try {
            byte[] bytes = new byte[1024];
            int result = inputStream.read(bytes);
            return new String(bytes, StandardCharsets.UTF_8);
        } catch (IOException e) {
            logger.error("Socket接收数据失败", e);
        }
        return "";
    }

    /**
     * 发送数据包, 判断Socket连接状态
     * @return
     */
    public boolean isSocketClosed() {
        try {
            socket.sendUrgentData(1);
            return false;
        } catch (IOException e) {
            return true;
        }
    }

    /**
     * 连接Socket服务器
     * @param host      IP地址
     * @param port      端口
     * @return          是否连接成功
     */
    public boolean connect(String host, int port){
        try{
            if (socket != null && !socket.isClosed()){
                logout();
            }
            this.socket = new Socket(host, port);
            socket.setOOBInline(true);
            socket.setKeepAlive(true);
            this.inputStream = socket.getInputStream();
            this.outputStream = socket.getOutputStream();
            return true;
        } catch (IOException e) {
            logger.error("连接Socket服务器失败", e);
            return false;
        }
    }

    /**
     * 关闭Socket连接
     */
    public void closeConnection() {
        if (socket != null && !socket.isClosed()){
            logout();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (socket != null && !socket.isClosed()){
            logout();
        }
    }
}
